# -*- coding: utf-8 -*-
# File : inventory_discovery.py
# Author: taoyahui
# Date : 2021/3/23
from utils import mysql_util
import nmap3
import json
import re


# 通过inventory_discovery 配置库获取配置信息
def inventory_discovery():
    conn = mysql_util.get_conn()
    cursor = mysql_util.get_cursor(conn)
    sql = f'select content, time_interval, is_avalilable from inventory_discovery'
    try:
        result = mysql_util.exec_sql(conn, cursor, sql)
        ips = get_active_host_ip(result[0][0])
        host_system_dict = get_host_system(ips)
        save_host(host_system_dict)
    except Exception as e:
        print(e)
    mysql_util.release(conn, cursor)
    return 'ok'


# 通过IP内容获取在线IP内容
def get_active_host_ip(content):
    content_dict = json.loads(content)
    ips = []
    try:
        ip_type_dict = content_dict['ip']
        for ip_content in ip_type_dict:
            type = ip_content['type']
            if type == 1 or type == 2:
                query_ip = ip_content['value']
            elif type == 3:
                pass
            ips.extend(nmap_util(query_ip))
        print(f"Find Intentory are :{ips}")
        return ips
    except Exception as e:
        print(e)


# 扫描主机的操作系统类型
# 参数：
#     ips: 列表形式的IP地址，可以是getActiveHostIP()的返回值
# 返回值：
#     字典，键为IP地址，值为操作系统类型，未扫描到的为 未知
#     这个方法只能扫描到大致的操作系统类型，准确的Linux发行版可通过Ansible获取，该方法非常耗时！
def get_host_system(ips):
    host_system_dict = {ip: '未知' for ip in ips}
    os_detection = nmap3.Nmap()
    for ip in ips:
        oss = os_detection.nmap_os_detection(ip, args="-A")
        osmatch = {}
        try:
            osmatch = oss[ip]['osmatch']
        except Exception as e:
            print(e)
        if osmatch:
            host_system_dict[ip] = osmatch[0]['name']
    return host_system_dict


# 保存host信息到inventory表中
def save_host(host_system_dict):
    conn = mysql_util.get_conn()
    cursor = mysql_util.get_cursor(conn)
    find_all_inventory_sql = 'select ip from inventory'
    try:
        exist_ips = [item[0] for item in mysql_util.exec_sql(conn, cursor, find_all_inventory_sql)]
        # 取已存在ip和检测ip的差集(在检测的IP池中， 不在已有的IP池中)
        d_set_ips = list(set(list(host_system_dict.keys())).difference(set(exist_ips)))
        for ip in d_set_ips:
            os_version = host_system_dict[ip]
            insert_sql = f'INSERT INTO inventory(ip, os) VALUES ("{ip}", "{os_version}")'
            print(insert_sql)
            mysql_util.exec_sql(conn, cursor, insert_sql)
        mysql_util.release(conn, cursor)
    except Exception as e:
        print(e)


# 使用nmap扫描获取ip信息
def nmap_util(ip_content=''):
    pattern = re.compile("(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])")
    nmap = nmap3.NmapHostDiscovery()
    result = nmap.nmap_no_portscan(ip_content)
    ips = [ip for ip in result if pattern.match(ip)]
    return ips


if __name__ == '__main__':
    content = '{"ip":[{"type":1,"value": "10.16.94.184"},{"type":1,"value": "10.18.140.81"}]}'
    ips = get_active_host_ip(content)
    # print(ips)
    host_system_dict = get_host_system(ips)
    # print(host_system_dict)
    # host_system_dict = {'10.16.94.184': 'Linux 3.10 - 4.11', '10.18.140.81': 'Linux 3.10 - 4.11'}
    save_host(host_system_dict)
    # save_host([])
    # host ={'10.16.94.184': 'Linux 3.10 - 4.11', '10.18.140.81': 'Linux 3.10 - 4.11'}
    # print(list(host.keys()))
    # a = ['192.168.1.24']
    # b = list(host.keys())
    # print(list(set(b).difference(set(a))))
